home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…ch: Other People's Memory / ADC Developer CD (1993-03) (''Other People's Memory'')_iso / Dev.CD Mar 93.iso / Technical Documentation / Sample Code / DTS.Lib & Samples / DTS.Draw / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-22  |  14.6 KB  |  588 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        Menu.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1990-1992 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11.  
  12.  
  13. /*****************************************************************************/
  14.  
  15.  
  16.  
  17. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  18. #include "App.Common.h"        /* Get the stuff in common with rez.            */
  19. #include "App.protos.h"        /* Get the prototypes for the application.        */
  20.  
  21. #ifndef __AppMenu__
  22. #include "App.Menu.h"
  23. #endif
  24.  
  25. #ifndef __DESK__
  26. #include <Desk.h>
  27. #endif
  28.  
  29. #ifndef __ERRORS__
  30. #include <Errors.h>
  31. #endif
  32.  
  33. #ifndef __MEMORY__
  34. #include <Memory.h>
  35. #endif
  36.  
  37. #ifndef __MENUS__
  38. #include <Menus.h>
  39. #endif
  40.  
  41. #ifndef __TOOLUTILS__
  42. #include <ToolUtils.h>
  43. #endif
  44.  
  45. #ifndef __TREEOBJ2__
  46. #include "TreeObj2.h"
  47. #endif
  48.  
  49. #ifndef __UTILITIES__
  50. #include "Utilities.h"
  51. #endif
  52.  
  53.  
  54.  
  55. /*****************************************************************************/
  56.  
  57.  
  58.  
  59. extern Boolean        gQuitApplication;
  60. extern Boolean        gHasAppleEvents;
  61. extern WindowPtr    gToolWindow;
  62. extern WindowPtr    gClipboardWindow;
  63.  
  64. static Boolean    DoAdjustFileMenu(WindowPtr window);
  65. static Boolean    DoAdjustEditMenu(WindowPtr window);
  66. static Boolean    DoAdjustArrangeMenu(WindowPtr window);
  67.  
  68.  
  69.  
  70. /*****************************************************************************/
  71. /*****************************************************************************/
  72.  
  73.  
  74.  
  75. /* •• Called by DTS.Lib..framework. •• */
  76.  
  77. /* Enable and disable menus based on the current state.  The user can only
  78. ** select enabled menu items.  We set up all the menu items before calling
  79. ** MenuSelect or MenuKey, since these are the only times that a menu item can
  80. ** be selected.  Note that MenuSelect is also the only time the user will see
  81. ** menu items.  This approach to deciding what enable/disable state a menu
  82. ** item has the advantage of concentrating all the decision-making in one
  83. ** place, as opposed to being spread throughout the application.  Other
  84. ** application designs may take a different approach that is just as valid. */
  85.  
  86. #pragma segment Menu
  87. void    DoAdjustMenus(void)
  88. {
  89.     WindowPtr    window;
  90.     Boolean        redrawMenuBar;
  91.  
  92.     window = FrontWindow();
  93.  
  94.     redrawMenuBar  = DoAdjustFileMenu(window);
  95.     redrawMenuBar |= DoAdjustEditMenu(window);
  96.     redrawMenuBar |= DoAdjustArrangeMenu(window);
  97.  
  98.     if (redrawMenuBar)
  99.         DrawMenuBar();
  100. }
  101.  
  102.  
  103.  
  104. /*****************************************************************************/
  105.  
  106.  
  107.  
  108. /* •• Called by DTS.Lib..framework. •• */
  109.  
  110. /* This is called when an item is chosen from the menu bar (after calling
  111. ** MenuSelect or MenuKey).  It performs the right operation for each command.
  112. ** It is good to have both the result of MenuSelect and MenuKey go to one
  113. ** routine like this to keep everything organized. */
  114.  
  115. #pragma segment Menu
  116. void    DoMenuCommand(long menuResult)
  117. {
  118.     short        menuID, menuItem, daRefNum, saveMode;
  119.     Str255        str;
  120.     FileRecHndl    frHndl, newFrHndl;
  121.     WindowPtr    window;
  122.     MenuHandle    menu;
  123.     Rect        tearRect;
  124.     OSErr        err;
  125.  
  126.     if (window = FrontWindowOfType(kwIsDocument))
  127.         frHndl = (FileRecHndl)GetWRefCon(window);
  128.             /* frHndl is valid only if it is one of our windows. */
  129.  
  130.     menuID = HiWord(menuResult);    /* Use macros for efficiency to get */
  131.     menuItem = LoWord(menuResult);    /* menu item number and menu number. */
  132.  
  133.     switch (menuID) {
  134.  
  135.         case mApple:
  136.             switch (menuItem) {
  137.                 case iAbout:    /* Bring up alert for About. */
  138.                     HCenteredAlert(rAboutAlert, nil, (ModalFilterProcPtr)AlertFilter);
  139.                     break;
  140.                 default:        /* All non-About items in this menu are DAs. */
  141.                     GetItem(GetMHandle(mApple), menuItem, str);
  142.                     daRefNum = OpenDeskAcc(str);
  143.                     break;
  144.             }
  145.             break;
  146.  
  147.         case mFile:
  148.             switch (menuItem) {
  149.                 case iNew:
  150.                     err = NewDocument(&frHndl, kDocFileType, true);
  151.                     if (!err) {
  152.                         err = DoNewWindow(frHndl, nil, FrontWindowOfType(kwIsDocument),
  153.                                           (WindowPtr)-1);
  154.                         if (err)
  155.                             DisposeDocument(frHndl);
  156.                     }
  157.                     if (err)
  158.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  159.                     break;
  160.                 case iOpen:
  161.                     err = OpenDocument(&frHndl, nil, fsRdWrPerm);
  162.                     if (!err) {
  163.                         err = DoNewWindow(frHndl, nil, FrontWindowOfType(kwIsDocument),
  164.                                           (WindowPtr)-1);
  165.                         if (err)
  166.                             DisposeDocument(frHndl);
  167.                     }
  168.                     if ((err) && (err != userCanceledErr))
  169.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  170.                     break;
  171.                 case iClose:
  172.                     DisposeOneWindow(window, kClose);
  173.                     break;
  174.                 case iSave:
  175.                 case iSaveAs:
  176.                     saveMode = (menuItem == iSave) ? kSave : kSaveAs;
  177.                     if ((*frHndl)->fileState.refNum == kInvalRefNum)
  178.                         saveMode = kSaveAs;
  179.                     err = SaveDocument(frHndl, window, saveMode);
  180.                     if ((err) && (err != userCanceledErr))
  181.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  182.                     break;
  183.                 case iDuplicate:
  184.                     err = DuplicateDocument(frHndl, &newFrHndl);
  185.                     if (!err) {
  186.                         err = DoNewWindow(newFrHndl, nil, FrontWindowOfType(kwIsDocument),
  187.                                           (WindowPtr)-1);
  188.                         if (err)
  189.                             DisposeDocument(newFrHndl);
  190.                     }
  191.                     if (err)
  192.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  193.                     break;
  194.                 case iPageSetup:
  195.                     DoSetCursor(&qd.arrow);
  196.                     PresentStyleDialog(frHndl);
  197.                     break;
  198.                 case iPrint:
  199.                     DoSetCursor(&qd.arrow);
  200.                     err = noErr;
  201.                     if (!(*frHndl)->d.doc.fhInfo.printRecValid)
  202.                         err = PresentStyleDialog(frHndl);
  203.                     if (!err) {
  204.                         err = PrintDocument(frHndl, true, true);
  205.                         PrintDocument(nil, false, false);
  206.                     }
  207.                     if ((err) && (err != userCanceledErr))
  208.                         HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  209.                     break;
  210.                 case iQuit:
  211.                     gQuitApplication = DisposeAllWindows();
  212.                     break;
  213.             }
  214.             break;
  215.  
  216.         case mEdit:            /* Call SystemEdit for DA editing & MultiFinder. */
  217.             if (!IsDAWindow(window)) {
  218.                 if (menuItem == iClipboard) {
  219.                     ShowHide(gClipboardWindow, !((WindowPeek)gClipboardWindow)->visible);
  220.                     CleanSendInFront(gClipboardWindow, FrontWindowOfType(kwIsDocument));
  221.                     break;
  222.                 }
  223.                 switch ((*frHndl)->fileState.sfType) {
  224.                     case kDocFileType:
  225.                         switch (menuItem) {
  226.                             case iUndo:
  227.                             case iRedo:
  228.                                 DoUndoTask((*frHndl)->d.doc.root, menuItem - iUndo, true);
  229.                                 break;
  230.                             case iCut:
  231.                             case iCopy:
  232.                             case iPaste:
  233.                                 DoClipboard(frHndl, menuItem);
  234.                                 break;
  235.                             case iClear:
  236.                                 DoDelete(frHndl);
  237.                                 break;
  238. #if VH_VERSION
  239.                             case iViewHier:
  240.                                 err = NewDocument(&frHndl, kViewHierFileType, false);
  241.                                 if (!err) {
  242.                                     err = DoNewWindow(frHndl, nil, FrontWindowOfType(kwIsDocument),
  243.                                                       (WindowPtr)-1);
  244.                                     if (err)
  245.                                         DisposeDocument(frHndl);
  246.                                 }
  247.                                 if (err)
  248.                                     HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  249.                                 break;
  250. #endif
  251.                         }
  252.                         break;
  253. #if VH_VERSION
  254.                     case kClipboardFileType:
  255.                         if (menuItem == iViewHier) {
  256.                             err = NewDocument(&frHndl, kViewHierFileType, false);
  257.                             if (!err) {
  258.                                 err = DoNewWindow(frHndl, nil, FrontWindowOfType(kwIsDocument),
  259.                                                   (WindowPtr)-1);
  260.                                 if (err)
  261.                                     DisposeDocument(frHndl);
  262.                             }
  263.                             if (err)
  264.                                 HCenteredAlert(rErrorAlert, nil, (ModalFilterProcPtr)AlertFilter);
  265.                         }
  266.                         break;
  267.                     case kViewHierFileType:
  268.                         BeginContent(window);
  269.                         switch (menuItem) {
  270.                             case iUndo:
  271.                                 CTEUndo();
  272.                                 break;
  273.                             case iCut:
  274.                             case iCopy:
  275.                             case iPaste:
  276.                             case iClear:
  277.                                   CTEClipboard(menuItem - iCut + 2);
  278.                                   break;
  279.                         }
  280.                         EndContent(window);
  281.                         break;
  282. #endif
  283.                 }
  284.             }
  285.             else SystemEdit(menuItem - 1);
  286.             break;
  287.  
  288.         case mArrange:
  289.             switch (menuItem) {
  290.                 case iShowHideToolPalette:
  291.                     ToolPaletteDisplay();
  292.                     break;
  293.                 default:
  294.                     DoArrange(frHndl, menuItem);
  295.                     break;
  296.             }
  297.             break;
  298.  
  299.         case mToolPalette:
  300.             menu = GetMHandle(mToolPalette);
  301.             switch (menuItem) {
  302.                 case -1:
  303.                     if (gToolWindow) {
  304.                         GetItem(menu, iTearInfo, str);
  305.                         BlockMove(str + 1, &tearRect, sizeof(Rect));
  306.                         MoveWindow(gToolWindow, tearRect.left, tearRect.top, false);
  307.                         ShowHide(gToolWindow, true);
  308.                         BringToFront(gToolWindow);
  309.                         HiliteWindows();
  310.                     }
  311.                     break;
  312.                 case iArrowTool:
  313.                 case iRectTool:
  314.                 case iRRectTool:
  315.                 case iOvalTool:
  316.                 case iPieTool:
  317.                     SetPaletteTool(menuItem - 1, false);
  318.                     break;
  319.             }
  320.     }
  321.  
  322.     HiliteMenu(0);        /* Unhighlight what MenuSelect (or MenuKey) hilited. */
  323. }
  324.  
  325.  
  326.  
  327. /*****************************************************************************/
  328. /*****************************************************************************/
  329.  
  330.  
  331.  
  332. /* This function either enables or disables a menu item. */
  333.  
  334. #pragma segment Menu
  335. void    EnableOrDisableItem(MenuHandle menu, short item, Boolean enable)
  336. {
  337.     if (enable)
  338.         EnableItem(menu, item);
  339.     else
  340.         DisableItem(menu, item);
  341. }
  342.  
  343.  
  344.  
  345. /*****************************************************************************/
  346.  
  347.  
  348.  
  349. #pragma segment Menu
  350. static Boolean    DoAdjustFileMenu(WindowPtr window)
  351. {
  352.     MenuHandle    menu;
  353.     FileRecHndl    frHndl;
  354.     short        i, enableItem;
  355.  
  356.     menu = GetMHandle(mFile);
  357.  
  358.     if (IsDAWindow(window)) {
  359.         for (i = iNew; i < iQuit; ++i) DisableItem(menu, i);
  360.         EnableItem(menu, iClose);    /* Let DAs do a close from the menu. */
  361.         return(false);
  362.     }
  363.  
  364.     EnableItem(menu, iNew);                /* Set these for the no-windows state. */
  365.     EnableItem(menu, iOpen);
  366.     if (MaxBlock() < 0x10000L) {
  367.         if (CompactMem(0x10000L) < 0x10000L) {
  368.             DisableItem(menu, iNew);    /* Running low on RAM. */
  369.             DisableItem(menu, iOpen);
  370.         }
  371.     }
  372.     DisableItem(menu, iClose);
  373.     DisableItem(menu, iSave);
  374.     DisableItem(menu, iSaveAs);
  375.     DisableItem(menu, iDuplicate);
  376.     DisableItem(menu, iPageSetup);
  377.     DisableItem(menu, iPrint);
  378.     if (window = FrontWindowOfType(kwIsDocument)) {
  379.         EnableItem(menu, iClose);
  380.         frHndl = (FileRecHndl)GetWRefCon(window);
  381.         if ((*frHndl)->fileState.sfType == kDocFileType) {
  382.             enableItem = GetWindowDirty(window);
  383.             if ((*frHndl)->fileState.refNum == kInvalRefNum)
  384.                 enableItem = true;
  385.             EnableOrDisableItem(menu, iSave, enableItem);
  386.             EnableItem(menu, iSaveAs);
  387.             EnableItem(menu, iDuplicate);
  388.         }
  389.         EnableItem(menu, iPageSetup);
  390.         EnableItem(menu, iPrint);
  391.     }
  392.  
  393.     return(false);
  394. }
  395.  
  396.  
  397.  
  398. /*****************************************************************************/
  399.  
  400.  
  401.  
  402. #pragma segment Menu
  403. static Boolean    DoAdjustEditMenu(WindowPtr window)
  404. {
  405.     MenuHandle        menu;
  406.     FileRecHndl        frHndl, frClip;
  407.     short            i, undoDepth, numUndos;
  408.     Boolean            haveDocument, ignore;
  409.     Str255            str;
  410.     StringPtr        cptr;
  411.     static Str32    clipboardText[3];
  412.  
  413.     menu = GetMHandle(mEdit);
  414.  
  415.     if (IsDAWindow(window)) {
  416.         EnableItem(menu, iUndo);
  417.         DisableItem(menu, iRedo);
  418.         EnableItem(menu, iCut);
  419.         EnableItem(menu, iCopy);
  420.         EnableItem(menu, iPaste);
  421.         EnableItem(menu, iClear);
  422.         DisableItem(menu, iClipboard);
  423. #if VH_VERSION
  424.         DisableItem(menu, iViewHier);
  425. #endif
  426.         return(false);
  427.     }
  428.  
  429.     for (i = iUndo; i <= iClear; ++i) DisableItem(menu, i);
  430.  
  431.     haveDocument = (window = FrontWindowOfType(kwIsDocument)) ? true : false;
  432.     frHndl = (haveDocument) ? (FileRecHndl)GetWRefCon(window) : nil;
  433.  
  434. #if VH_VERSION
  435.     EnableOrDisableItem(menu, iViewHier, haveDocument);
  436. #endif
  437.  
  438.     EnableItem(menu, iClipboard);
  439.     if (!clipboardText[0][0]) {
  440.         GetItem(menu, iClipboard, str);
  441.         p2c(str);
  442.         for (i = 0; str[i]; ++i)
  443.             if (str[i] == ',')
  444.                 str[i] = 0;
  445.         for (cptr = str, i = 0; i < 3; ++i) {
  446.             c2p((char *)cptr);
  447.             pcpy(clipboardText[i], cptr);
  448.             cptr += (cptr[0] + 1);
  449.         }
  450.     }
  451.     if (gClipboardWindow) {
  452.         i = (((WindowPeek)gClipboardWindow)->visible) ? 1 : 0;
  453.         pcpy(str, clipboardText[i]);
  454.         pcat(str, clipboardText[2]);
  455.         SetItem(menu, iClipboard, str);
  456.         EnableItem(menu, iClipboard);
  457.     }
  458.  
  459.     if (haveDocument) {
  460.         switch ((*frHndl)->fileState.sfType) {
  461.             case kDocFileType:
  462.                 GetUndoInfo(frHndl, &undoDepth, &numUndos);
  463.                 if (undoDepth)
  464.                     EnableItem(menu, iUndo);
  465.                 if (undoDepth < numUndos)
  466.                     EnableItem(menu, iRedo);
  467.                 if (mDerefRoot((*frHndl)->d.doc.root)->numSelected) {
  468.                     EnableItem(menu, iCut);
  469.                     EnableItem(menu, iCopy);
  470.                     EnableItem(menu, iClear);
  471.                 }
  472.                 frClip = (FileRecHndl)GetWRefCon(gClipboardWindow);
  473.                 if ((*((*frClip)->d.doc.root))->numChildren)
  474.                     EnableItem(menu, iPaste);
  475.                 break;
  476. #if VH_VERSION
  477.             case kViewHierFileType:
  478.                 CTEEditMenu(&ignore, mEdit, iUndo, iCut);
  479.                 break;
  480. #endif
  481.         }
  482.     }
  483.  
  484.     return(false);
  485. }
  486.  
  487.  
  488.  
  489. /*****************************************************************************/
  490.  
  491.  
  492.  
  493. #pragma segment Menu
  494. static Boolean    DoAdjustArrangeMenu(WindowPtr window)
  495. {
  496.     MenuHandle        menu;
  497.     short            i, numChildren, numSelected, cnum, flag;
  498.     Boolean            haveDocument, redrawMenuBar;
  499.     FileRecHndl        frHndl;
  500.     TreeObjHndl        root, chndl;
  501.     Str255            str;
  502.     StringPtr        cptr;
  503.     static Boolean    arrangeMenuEnabled = true;
  504.     static Str32    toolPaletteText[3];
  505.  
  506.     menu = GetMHandle(mArrange);
  507.  
  508.     if (IsDAWindow(window)) {
  509.         for (i = iShowHideToolPalette; i <= iUngroup; ++i) DisableItem(menu, i);
  510.         redrawMenuBar = arrangeMenuEnabled;
  511.         arrangeMenuEnabled = false;
  512.         return(redrawMenuBar);
  513.     }
  514.  
  515.     haveDocument = (window = FrontWindowOfType(kwIsDocument)) ? true : false;
  516.     frHndl = (haveDocument) ? (FileRecHndl)GetWRefCon(window) : nil;
  517.  
  518.     EnableItem(menu, iShowHideToolPalette);
  519.     if (!toolPaletteText[0][0]) {
  520.         GetItem(menu, iShowHideToolPalette, str);
  521.         p2c(str);
  522.         for (i = 0; str[i]; ++i)
  523.             if (str[i] == ',')
  524.                 str[i] = 0;
  525.         for (cptr = str, i = 0; i < 3; ++i) {
  526.             c2p((char *)cptr);
  527.             pcpy(toolPaletteText[i], cptr);
  528.             cptr += (cptr[0] + 1);
  529.         }
  530.     }
  531.     if (gToolWindow) {
  532.         i = (((WindowPeek)gToolWindow)->visible) ? 1 : 0;
  533.         pcpy(str, toolPaletteText[i]);
  534.         pcat(str, toolPaletteText[2]);
  535.         SetItem(menu, iShowHideToolPalette, str);
  536.         EnableItem(menu, iShowHideToolPalette);
  537.     }
  538.  
  539.     for (i = iMoveForward; i <= iUngroup; ++i) {
  540.         CheckItem(menu, i, false);
  541.         DisableItem(menu, i);
  542.     }
  543.     if (haveDocument) {
  544.         if ((*frHndl)->fileState.sfType == kDocFileType) {
  545.             root        = (*frHndl)->d.doc.root;
  546.             numChildren = (*root)->numChildren;
  547.             numSelected = mDerefRoot(root)->numSelected;
  548.             if (numSelected) {
  549.                 for (cnum = (*root)->numChildren; cnum;) {
  550.                     chndl = GetChildHndl(root, --cnum);
  551.                     if (DoTreeObjMethod(chndl, GETSELECTMESSAGE, 0))
  552.                         if ((*chndl)->type == GROUPOBJ)
  553.                             EnableItem(menu, iUngroup);
  554.                 }
  555.             }
  556.             if ((numSelected) && (numChildren > 1)) {
  557.                 if ((flag = numSelected) == 1) {
  558.                     chndl = GetChildHndl(root, 0);
  559.                     if (DoTreeObjMethod(chndl, GETSELECTMESSAGE, 0))
  560.                         --flag;
  561.                 }
  562.                 if (flag) {
  563.                     EnableItem(menu, iMoveForward);
  564.                     EnableItem(menu, iMoveToFront);
  565.                 }
  566.                 if ((flag = numSelected) == 1) {
  567.                     chndl = GetChildHndl(root, -1);        /* Last child. */
  568.                     if (DoTreeObjMethod(chndl, GETSELECTMESSAGE, 0))
  569.                         --flag;
  570.                 }
  571.                 if (flag) {
  572.                     EnableItem(menu, iMoveBackward);
  573.                     EnableItem(menu, iMoveToBack);
  574.                 }
  575.             }
  576.             if (numSelected > 1)
  577.                 EnableItem(menu, iGroup);
  578.         }
  579.     }
  580.  
  581.     redrawMenuBar = !arrangeMenuEnabled;
  582.     arrangeMenuEnabled = true;
  583.     return(redrawMenuBar);
  584. }
  585.  
  586.  
  587.  
  588.